import { Captcha, CaptchaService, CaptchaType } from "@mallfoundry/captcha"
import { getResponseMessage } from "@mallfoundry/client/message"
import { UserRetake, UserRetakeMode, UserService } from "@mallfoundry/keystone/identity"
import { Alert, Button, Card, Col, Form, Input, Row, Space, Statistic, Typography } from "antd"
import { ValidateStatus } from "antd/lib/form/FormItem"
import *  as CryptoJS from "crypto-js"
import * as _ from "lodash"
import * as React from "react"
import { useState } from "react"
import { Link, useHistory } from "react-router-dom"
import classes from "./index.module.scss"

const { Text, Link: TextLink } = Typography
const { Countdown } = Statistic

export default function Retake() {
  const [form] = Form.useForm()
  const history = useHistory()
  const [signing, setSigning] = useState(false)
  const [errorAlert, setErrorAlert] = useState("")
  const [userFound, setUserFound] = useState(false)
  const [phoneValidateStatus, setPhoneValidateStatus] = useState("" as ValidateStatus)
  const [captchaLoading, setCaptchaLoading] = useState(false)
  const [captchaSending, setCaptchaSending] = useState(false)
  const [captchaSendingDeadline, setCaptchaSendingDeadline] = useState(0)
  const [captchaToken, setCaptchaToken] = useState("")

  function handleRetake(values: any) {
    const userRetake = new UserRetake()
    userRetake.mode = UserRetakeMode.PhoneCaptcha
    userRetake.password = CryptoJS.MD5(values.password).toString()
    userRetake.countryCode = "86"
    userRetake.phone = values.phone
    userRetake.captchaToken = captchaToken
    userRetake.captchaCode = values.captchaCode
    setSigning(true)
    UserService.retakeUser(userRetake)
      .then(() => history.push(`/login`))
      .catch(({ response }) => {
        setErrorAlert(getResponseMessage(response))
        setSigning(false)
      })
  }

  function handleSendCaptcha() {
    form.validateFields(["phone"])
      .then(({ phone }) => {
        const newCaptcha = new Captcha()
        newCaptcha.type = CaptchaType.Sms
        newCaptcha.parameters = {
          countryCode: "86",
          phone,
        }
        setCaptchaLoading(true)
        CaptchaService.generateCaptcha(newCaptcha)
          .then(({ intervals = 0, token = "" }) => {
            setCaptchaSending(true)
            setCaptchaSendingDeadline(Date.now() + intervals)
            setCaptchaToken(token)
          })
          .catch(({ response }) => setErrorAlert(getResponseMessage(response)))
          .finally(() => setCaptchaLoading(false))
      })
  }

  function validateFindUser(rule: any, phone: string) {
    const pattern = /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/
    return new Promise<void>((resolve, reject) => {
      if (_.isEmpty(phone)) {
        reject("请输入手机号")
        setPhoneValidateStatus("error")
      } else if (!pattern.test(phone)) {
        reject("手机号格式不正确")
        setPhoneValidateStatus("error")
      } else {
        setPhoneValidateStatus("validating")
        UserService
          .findUser({ countryCode: "86", phone })
          .then(user => {
            setUserFound(true)
            if (user) {
              setPhoneValidateStatus("success")
              resolve()
            } else {
              setPhoneValidateStatus("error")
              reject("手机号不存在")
            }
          })
      }
    })
  }

  return (
    <div className={classes.Retake}>
      <Row>
        <Col offset={8} span={7}>
          <Card bordered={false} title={<h3>找回密码</h3>}>
            {errorAlert && <Form.Item>
              <Alert type="error" message={errorAlert} closable afterClose={() => setErrorAlert("")}/>
            </Form.Item>}
            <Form name="RetakeForm" size="large" form={form} onFinish={handleRetake}>
              <Form.Item name="phone" rules={[{ validator: validateFindUser }]}
                         hasFeedback={userFound} validateStatus={phoneValidateStatus}>
                <Input placeholder="请输入手机号"/>
              </Form.Item>
              <Form.Item name="captchaCode" rules={[{ required: true, message: "请输入短信验证码" }]}
                         hasFeedback={captchaLoading} validateStatus={captchaLoading ? "validating" : undefined}>
                <Input placeholder="输入短信验证码"
                       suffix={<>
                         {!captchaLoading && !captchaSending &&
                         <TextLink className={classes.GetCaptcha} onClick={handleSendCaptcha}>获得验证码</TextLink>}
                         {!captchaLoading && captchaSending &&
                         <Text type="secondary" className={classes.CaptchaSending}>
                           <Countdown value={captchaSendingDeadline} format="ss 秒后可重发"
                                      onFinish={() => setCaptchaSending(false)}/>
                         </Text>}
                       </>}/>
              </Form.Item>
              <Form.Item name="password" rules={[{
                pattern: /(?=.*[0-9])(?=.*[a-zA-Z]).{8,20}/,
                message: "密码长度在8-20个字之间，必须同时包含字母和数字",
              }]}>
                <Input.Password placeholder="设置密码（8-20个字，包含字母和数字）"/>
              </Form.Item>
              <Form.Item>
                <Button block type="primary" htmlType="submit" loading={signing}>
                  {signing ? "找回中..." : "立即找回"}
                </Button>
              </Form.Item>
              <Form.Item noStyle>
                <Row justify="space-between">
                  <Col/>
                  <Col className={classes.BottomActions}>
                    <Space>
                      <Text type="secondary">已有帐号?</Text>
                      <Link to="/login">登录</Link>
                    </Space>
                  </Col>
                </Row>
              </Form.Item>
            </Form>
          </Card>
        </Col>
      </Row>
    </div>

  )
}
